package com.spddr.pmos.rpt.impl;

import java.util.List;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.QueryParam;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Hours;
import org.joda.time.Interval;
import org.joda.time.LocalDate;
import org.joda.time.Minutes;
import org.joda.time.Months;
import org.joda.time.Period;
import org.joda.time.Years;
import org.springframework.beans.factory.annotation.Autowired;

import com.spddr.pmos.domain.TreeLevel;
import com.spddr.pmos.jpa.ObjectDataStorage;
import com.spddr.pmos.jpa.ObjectDataStorageId;
import com.spddr.pmos.repos.ObjectDataStorageRepos;
import com.spddr.pmos.rpt.RptPivotChart;
import com.spddr.pmos.rpt.pojo.CellValue;

import cn.seqdata.tags.Point;
import cn.seqdata.tags.RegularPart;
import cn.seqdata.tags.RegularValues;
import cn.seqdata.tags.common.IdTags;
import cn.seqdata.tsdb.drds.cell.CellHistorian;
import cn.seqdata.tsdb.drds.cell.CellTemplate;

public abstract class AbstractPivotChartImpl implements RptPivotChart<CellValue> {

	@Autowired
	protected CellTemplate<IdTags, Point<IdTags>> cellTemplate;
	@Autowired
	protected ObjectDataStorageRepos storageRepos;

	@QueryParam("id")
	protected long id;
	@QueryParam("level")
	protected TreeLevel level;
	@QueryParam("metric")
	protected String metric;
	@QueryParam("date")
	protected LocalDate date;
	@QueryParam("interval")
	@DefaultValue("p1d")
	protected Period interval;

	protected RegularValues<IdTags, Point<IdTags>> sim(int step) {
		Point<IdTags> point = new Point<>(metric, new IdTags(id));

		int size = Days.ONE.toPeriod().equals(interval)
				? Minutes.minutesBetween(getStartTime(), getEndTime()).getMinutes() / step
				: Days.daysBetween(getStartTime(), getEndTime()).getDays() / step;

		double arrays[] = new double[size];
		for (int i = 0; i < arrays.length; ++i) {
			arrays[i] = Math.random() * 1000;
		}

		RegularPart values = new RegularPart(getStartTime(),
				Days.ONE.toPeriod().equals(interval) ? Minutes.minutes(step).toPeriod() : Days.days(step).toPeriod(),
				arrays);
		return new RegularValues<>(point, values);
	}

	protected Period intervalOfStorage() {
		return Hours.ONE.toPeriod();
	}

	protected RegularValues<IdTags, Point<IdTags>> load(int objectType, long id, String metric) {
		return load(objectType, id, metric, intervalOfStorage());
	}

	protected RegularValues<IdTags, Point<IdTags>> load(int objectType, long id, String metric, Period interval) {
		ObjectDataStorage storage = storageRepos.getOne(new ObjectDataStorageId(objectType, metric, interval));

		CellHistorian<IdTags, Point<IdTags>> cellHistorian = new CellHistorian<>(cellTemplate, storage.getTableName());

		Interval duration = new Interval(getStartTime(), getEndTime());
		Point<IdTags> point = new Point<>(metric, new IdTags(id));
		return cellHistorian.query(point, duration, storage.getId().getInterval());
	}

	protected DateTime getStartTime() {
		if (Months.ONE.toPeriod().equals(interval)) {
			return date.withDayOfMonth(1).toDateTimeAtStartOfDay();
		} else if (Years.ONE.toPeriod().equals(interval)) {
			return date.withMonthOfYear(1).withDayOfMonth(1).toDateTimeAtStartOfDay();
		}
		return date.toDateTimeAtStartOfDay();
	}

	protected DateTime getEndTime() {
		if (Months.ONE.toPeriod().equals(interval)) {
			return getStartTime().plusMonths(1);
		} else if (Years.ONE.toPeriod().equals(interval)) {
			return getStartTime().plusYears(1);
		}
		return getStartTime().plusDays(1);
	}

	@Override
	public void savePivot(List<CellValue> values) {
		// TODO Auto-generated method stub
	}

}
